package memento

import "C"

// Memento 备忘录的窄接口，没有任何方法定义
type Memento interface {
}

// MementoImpl 真正的备忘录对象，实现备忘录窄接口
type MementoImpl struct {
	// 示意，表示需要保存的状态
	state string
}

func NewMementoImpl(state string) *MementoImpl {
	return &MementoImpl{
		state: state,
	}
}

// GetState 创建过后，一般只让外面来访问数据，而不再修改数据，因此只有getter
func (m *MementoImpl) GetState() string {
	return m.state
}

// Originator 原发器对象
type Originator struct {
	// state 示意，表示源发器状态
	state string
	// 实现成私有内部类，不让外部访问
	memento Memento
}

// CreateMemento 创建保存元发起对象的状态的备忘录对象
// 返回创建好的备忘录对象
func (o *Originator) CreateMemento() Memento {
	return NewMementoImpl(o.state)
}

// SetMemento 重新设置原发器对象的状态，让其回到备忘录对象记录的状态
func (o *Originator) SetMemento(memento Memento) {
	mementoImpl := memento.(*MementoImpl)
	o.state = mementoImpl.GetState()
}

func (o *Originator) Process() {
	o.state += "==>process"
}

// Caretaker 负责保存备忘录的对象
type Caretaker struct {
	// 记录被保存的备忘录对象
	mementos []Memento
}

// saveMemento 保存备忘录对象
func (c *Caretaker) saveMemento(memento Memento) {
	c.mementos = append(c.mementos, memento)
}

// retriveMemento 获取被保存的备忘录对象
func (c *Caretaker) retriveMemento() Memento {
	ret := c.mementos[0]
	c.mementos = c.mementos[1:]
	return ret
}
